package com.szholly.plug.safe.entity.fun;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import org.springframework.stereotype.Component;

import com.szholly.utils.spring.SpringBeanFactory;
import com.szholly.utils.util.StringUtils;
import com.szholly.utils.util.TreeDataNode;
import com.szholly.data.general.GlobalDataType;
import com.szholly.data.general.IDomain;
import com.szholly.data.general.IQueryMap;
import com.szholly.data.general.ITable;
import com.szholly.data.general.ITableFactory;
import com.szholly.data.general.QueryMap;
import com.szholly.data.general.RowBase;
import com.szholly.data.general.interceptor.DbEditInterceptorClass;
import com.szholly.data.general.interceptor.DbEditType;
import com.szholly.data.general.interceptor.InterceptorRegister;

/**
 * 定义数据权限拦截器，处理数据权限在指定字典域情况下，自动批量生成数据
 */
@Component
public class DataFunctionInterceptor extends DbEditInterceptorClass {
	/**
	 * 注册拦截接口
	 */
	static {
		DataFunctionInterceptor interceptor = new DataFunctionInterceptor();
		InterceptorRegister.RegDbInterceptor(interceptor);
	}
	
	public DataFunctionInterceptor(){
		this.regTableName(DataFunctionService.TABLE_NAME);
	}

	@Override
	public void BeforeDbEditOption(ITable table, Object editEntitys,
			DbEditType editType) {
		// 如果是新增，并且状态值为空，处理默认值
		if((editType == DbEditType.Insert || editType == DbEditType.Update) 
				&& editEntitys instanceof RowBase){
			RowBase row = (RowBase)editEntitys;
			String domainName = (String)row.getValue(GlobalDataType.String, DataFunctionEntity.FIELD_DOMAINNAME);
			if(StringUtils.IsNullOrSpace(domainName)){
				return;
			}
			row.setValue(DataFunctionEntity.FIELD_DOMAINNAME, "");
			
			if(editType == DbEditType.Update){
				editType = DbEditType.Insert;
				
				// 先删除，再保存
				IQueryMap queryMap = new QueryMap();
				queryMap.getWhereMap().put(DataFunctionEntity.FIELD_FUNCTIONID, row.getValue(DataFunctionEntity.FIELD_FUNCTIONID));
				table.delete(queryMap);
				
				row.setIsNew(true);
			}
			
			// 获取字典信息
			String[] domainMsg = domainName.split(":");
			String tableName = domainMsg[0];
			String domianName = domainMsg[1];
			
			tableName = tableName.toUpperCase();
			ITableFactory tableFactory = (ITableFactory) SpringBeanFactory.getBean("TableFactory");
			IDomain domainTable = tableFactory.openDomain(tableName, domianName);
			List<DataFunctionEntity> functionEntityList = new ArrayList<DataFunctionEntity>();
			if(domainTable==null){
				return;
			}
			
			List<TreeDataNode> treeDataList = domainTable.getDatasEx();
			if(treeDataList==null || treeDataList.size()<=0){
				return;
			}
			
			Integer jb = (Integer)row.getValue(GlobalDataType.Int32, DataFunctionEntity.FIELD_JB);
			jb += 1;
			int order = 1;
			String pId = (String)row.getValue(GlobalDataType.String, DataFunctionEntity.FIELD_FUNCTIONID);
			HashMap<String, List<RowBase>> childValues = row.getChildValues();
			row.setValue(DataFunctionEntity.FIELD_ISCHILD, "0");
			
			for(TreeDataNode treeData : treeDataList){
				String id = treeData.getid();
				String text = treeData.getText();
				String state = treeData.getState();
				String isChild = "0";
				if(state.equals("closed")){
					isChild = "0";
				}else{
					isChild = "1";
				}
				
				DataFunctionEntity functionEntity = new DataFunctionEntity();
				functionEntity.setPID(pId);
				UUID guid = UUID.randomUUID();
				String functionId = guid.toString();
				functionEntity.setFunctionID(functionId);
				functionEntity.setFunctionName(text);
				functionEntity.setFunctionType("2");
				functionEntity.setOrder(order);
				functionEntity.setJb(jb.toString());
				functionEntity.setIsChild(isChild);
				HashMap<String, List<RowBase>> copyChildValues = copyChildValues(childValues, id);
				functionEntity.setChildValues(copyChildValues);
				functionEntityList.add(functionEntity);
				
				setChild(treeData, functionEntityList, functionId, childValues, jb+1);
				
				order++;
			}
			// 清除子表
			if(childValues!=null){
				Set<String> keys = childValues.keySet();
				for(String key : keys){
					List<RowBase> copyRowList = new ArrayList<RowBase>();
					childValues.put(key, copyRowList);
				}
			}
			row.setChildValues(null);
			table.save(functionEntityList);
		}
	}
	
	private void setChild(TreeDataNode pTreeData, List<DataFunctionEntity> functionEntityList,
			String pId, HashMap<String, List<RowBase>> childValues, Integer jb){
		List<TreeDataNode> treeDataList = pTreeData.getChildren();
		if(treeDataList==null || treeDataList.size()<=0){
			return;
		}
		
		int order = 1;
		
		for(TreeDataNode treeData : treeDataList){
			String id = treeData.getid();
			String text = treeData.getText();
			String state = treeData.getState();
			String isChild = "0";
			if(state.equals("closed")){
				isChild = "1";
			}
			
			DataFunctionEntity functionEntity = new DataFunctionEntity();
			functionEntity.setPID(pId);
			UUID guid = UUID.randomUUID();
			String functionId = guid.toString();
			functionEntity.setFunctionID(functionId);
			functionEntity.setFunctionName(text);
			functionEntity.setFunctionType("2");
			functionEntity.setOrder(order);
			functionEntity.setJb(jb.toString());
			functionEntity.setIsChild(isChild);
			HashMap<String, List<RowBase>> copyChildValues = copyChildValues(childValues, id);
			functionEntity.setChildValues(copyChildValues);
			functionEntityList.add(functionEntity);
			
			setChild(treeData, functionEntityList, functionId, childValues, jb+1);
			
			order++;
		}
	}
	
	private HashMap<String, List<RowBase>> copyChildValues(HashMap<String, List<RowBase>> childValues, String id){
		if(childValues==null){
			return null;
		}
		
		HashMap<String, List<RowBase>> copyChildValues = new HashMap<String, List<RowBase>>();
		Set<String> keys = childValues.keySet();
		for(String key : keys){
			List<RowBase> rowList = childValues.get(key);
			List<RowBase> copyRowList = new ArrayList<RowBase>();
			for(RowBase row : rowList){
				RowBase copyRow = (RowBase)row.clone();
				String tableWhere = (String)copyRow.getValue(GlobalDataType.String, DataFunctionItemEntity.FIELD_TABLEWHERE);
				if(!StringUtils.IsNullOrSpace(tableWhere)){
					tableWhere = tableWhere.replace("{domaincode}", id);
				}
				copyRow.setValue(DataFunctionItemEntity.FIELD_TABLEWHERE, tableWhere);
				copyRow.setIsNew(true);
				UUID guid = UUID.randomUUID();
				copyRow.setValue(DataFunctionItemEntity.FIELD_FUNCTIONITEMID, guid.toString());
				copyRowList.add(copyRow);
			}
			copyChildValues.put(key, copyRowList);
		}
		
		return copyChildValues;
	}

	@Override
	public void DbEditOptionException(ITable table, Object editEntitys,
			DbEditType editType, Exception ex) {
	}

	@Override
	public void AfterDbEditOption(ITable table, Object editEntitys,
			DbEditType editType) {
	}

	@Override
	public String getInterceptorName() {
		return "定义数据权限拦截器，处理数据权限在指定字典域情况下，自动批量生成数据";
	}
}